<!DOCTYPE html>
<html>
    <head>
    <!--
        © Material Theme
        https://github.com/viosey/hexo-theme-material
        Version: 1.2.6 -->

    <!-- Title -->
    
    <title>
        
            用Python做了一个点名软件 | 
        
        豆沙包的博客
    </title>

    <!-- Favicons -->
    <link rel="icon shortcut" type="image/ico" href="/img/favicon.png">
    <link rel="icon" sizes="192x192" href="/img/favicon.png">
    <link rel="apple-touch-icon" href="/img/favicon.png">

    <!-- Meta & Info -->
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="theme-color" content="#0097A7">
    <meta name="author" content="Doushabao">
    <meta name="description" content="豆沙包的个人博客，目前正在建设中。">
    <meta name="keywords" content="">

    <!--iOS -->
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-title" content="Title">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="HandheldFriendly" content="True">
    <meta name="MobileOptimized" content="480">

    <!-- Add to homescreen for Chrome on Android -->
    <meta name="mobile-web-app-capable" content="yes">

    <!-- Add to homescreen for Safari on iOS -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="apple-mobile-web-app-title" content="豆沙包的博客">

    <!-- The Open Graph protocol -->
    <meta property="og:url" content="https://doushabao_233.gitee.io">
    <meta property="og:type" content="blog">
    <meta property="og:title" content="用Python做了一个点名软件 | 豆沙包的博客">
    <meta property="og:description" content="豆沙包的个人博客，目前正在建设中。">

    <!--[if lte IE 9]>
        <link rel="stylesheet" href="/css/ie-blocker.css">

        
            <script src="/js/ie-blocker.zhCN.js"></script>
        
    <![endif]-->

    <!-- Import CSS -->
    
<link rel="stylesheet" href="/css/material.min.css">

    
<link rel="stylesheet" href="/css/style.min.css">

    <!-- Config CSS -->


<!-- Other Styles -->
<style>
    body, html {
        font-family: Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
    }

    a {
        color: #00838F;
    }

    .mdl-card__media,
    #search-label,
    #search-form-label:after,
    #scheme-Paradox .hot_tags-count,
    #scheme-Paradox .sidebar_archives-count,
    #scheme-Paradox .sidebar-colored .sidebar-header,
    #scheme-Paradox .sidebar-colored .sidebar-badge{
        background-color: #0097A7 !important;
    }

    /* Sidebar User Drop Down Menu Text Color */
    #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:hover,
    #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:focus {
        color: #0097A7 !important;
    }

    #post_entry-right-info,
    .sidebar-colored .sidebar-nav li:hover > a,
    .sidebar-colored .sidebar-nav li:hover > a i,
    .sidebar-colored .sidebar-nav li > a:hover,
    .sidebar-colored .sidebar-nav li > a:hover i,
    .sidebar-colored .sidebar-nav li > a:focus i,
    .sidebar-colored .sidebar-nav > .open > a,
    .sidebar-colored .sidebar-nav > .open > a:hover,
    .sidebar-colored .sidebar-nav > .open > a:focus,
    #ds-reset #ds-ctx .ds-ctx-entry .ds-ctx-head a {
        color: #0097A7 !important;
    }

    .toTop {
        background: #757575 !important;
    }

    .material-layout .material-post>.material-nav,
    .material-layout .material-index>.material-nav,
    .material-nav a {
        color: #757575;
    }

    #scheme-Paradox .MD-burger-layer {
        background-color: #757575;
    }

    #scheme-Paradox #post-toc-trigger-btn {
        color: #757575;
    }

    .post-toc a:hover {
        color: #00838F;
        text-decoration: underline;
    }
</style>


<!-- Theme Background Related-->

    <style>
        body{
            background-color: #F5F5F5;
        }

        /* blog_info bottom background */
        #scheme-Paradox .material-layout .something-else .mdl-card__supporting-text{
            background-color: #fff;
        }
    </style>




<!-- Fade Effect -->

    <style>
        .fade {
            transition: all 800ms linear;
            -webkit-transform: translate3d(0,0,0);
            -moz-transform: translate3d(0,0,0);
            -ms-transform: translate3d(0,0,0);
            -o-transform: translate3d(0,0,0);
            transform: translate3d(0,0,0);
            opacity: 1;
        }

        .fade.out{
            opacity: 0;
        }
    </style>


    
<script src="/js/jquery.min.js"></script>


    
<link rel="stylesheet" href="/css/highlight/solarized-white.css">


    <!-- UC Browser Compatible-->
    <script>
        var agent = navigator.userAgent.toLowerCase();
        if(agent.indexOf('ucbrowser')>0) {
            document.write('
<link rel="stylesheet" href="/css/uc.css">
');
            alert('由于 UC 浏览器使用极旧的内核，而本网站使用了一些新的特性。\n为了您能更好的浏览，推荐使用 Chrome 或 Firefox 浏览器。');
        }
    </script>

    <!-- Custom Head -->
    
<meta name="generator" content="Hexo 6.3.0"></head>


    
        <body id="scheme-Paradox">
            <div class="material-layout  mdl-js-layout has-drawer is-upgraded">
                

                <!-- Main Container -->
                <main class="material-layout__content" id="main">

                    <!-- Top Anchor -->
                    <div id="top"></div>

                    
                        <!-- Hamburger Button -->
                        <button class="MD-burger-icon sidebar-toggle">
                            <span class="MD-burger-layer"></span>
                        </button>
                    

                    <!-- Post TOC -->

    
    <!-- Back Button -->
    <!--
    <div class="material-back" id="backhome-div" tabindex="0">
        <a class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"
           href="#" onclick="window.history.back();return false;"
           target="_self"
           role="button"
           data-upgraded=",MaterialButton,MaterialRipple">
            <i class="material-icons" role="presentation">arrow_back</i>
            <span class="mdl-button__ripple-container">
                <span class="mdl-ripple"></span>
            </span>
        </a>
    </div>
    -->

    <!-- Left aligned menu below button -->
    <button id="post-toc-trigger-btn"
        class="mdl-button mdl-js-button mdl-button--icon">
        <i class="material-icons">format_list_numbered</i>
    </button>

    <ul class="post-toc-wrap mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="post-toc-trigger-btn">
        <ol class="post-toc"><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#%E8%B5%B7%E5%9B%A0%E2%80%A6"><span class="post-toc-number">1.</span> <span class="post-toc-text">起因…</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#%E5%89%8D%E6%8E%92%E6%8F%90%E9%86%92"><span class="post-toc-number">2.</span> <span class="post-toc-text">前排提醒</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#%E5%88%86%E6%9E%90"><span class="post-toc-number">3.</span> <span class="post-toc-text">分析</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#%E7%BC%96%E7%A8%8B"><span class="post-toc-number">4.</span> <span class="post-toc-text">编程</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#%E8%BF%98%E6%98%AF%E4%B8%8D%E5%A4%9F%E8%BF%87%E7%98%BE"><span class="post-toc-number">5.</span> <span class="post-toc-text">还是不够过瘾</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#%E5%AE%8C%E6%95%B4%E4%BB%A3%E7%A0%81"><span class="post-toc-number">6.</span> <span class="post-toc-text">完整代码</span></a></li></ol>

        <!--
        <li class="mdl-menu__item">
            Some Action
        </li>
        -->
    </ul>




<!-- Layouts -->

    <!-- Post Module -->
    <div class="material-post_container">

        <div class="material-post mdl-grid">
            <div class="mdl-card mdl-shadow--4dp mdl-cell mdl-cell--12-col">

                <!-- Post Header(Thumbnail & Title) -->
                
    <!-- Paradox Post Header -->
    
        
            <!-- Random Thumbnail -->
            <div class="post_thumbnail-random mdl-card__media mdl-color-text--grey-50">
            <script>
    var randomNum = Math.floor(Math.random() * 19 + 1);

    $('.post_thumbnail-random').css('background-image', 'url(' + '/img/random/material-' + randomNum + '.png' + ')');
</script>

        
    
            <p class="article-headline-p">
                用Python做了一个点名软件
            </p>
        </div>





                
                    <!-- Paradox Post Info -->
                    <div class="mdl-color-text--grey-700 mdl-card__supporting-text meta">

    <!-- Author Avatar -->
    <div id="author-avatar">
        <img src="/img/avatar.png" width="44px" height="44px" alt="Author Avatar"/>
    </div>
    <!-- Author Name & Date -->
    <div>
        <strong>Doushabao</strong>
        <span>3月 17, 2023</span>
    </div>

    <div class="section-spacer"></div>

    <!-- Favorite -->
    <!--
        <button id="article-functions-like-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon btn-like">
            <i class="material-icons" role="presentation">favorite</i>
            <span class="visuallyhidden">favorites</span>
        </button>
    -->

    <!-- Qrcode -->
    

    <!-- Tags (bookmark) -->
    
    <button id="article-functions-viewtags-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
        <i class="material-icons" role="presentation">bookmark</i>
        <span class="visuallyhidden">bookmark</span>
    </button>
    <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-functions-viewtags-button">
        <li class="mdl-menu__item">
        
    </ul>
    

    <!-- Share -->
    <button id="article-fuctions-share-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
    <i class="material-icons" role="presentation">share</i>
    <span class="visuallyhidden">share</span>
</button>
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-fuctions-share-button">
    

    

    <!-- Share Weibo -->
    
        <a class="post_share-link" href="http://service.weibo.com/share/share.php?appkey=&title=用Python做了一个点名软件&url=https://doushabao_233.gitee.io//2023/03/17/%E7%94%A8Python%E5%81%9A%E4%BA%86%E4%B8%80%E4%B8%AA%E7%82%B9%E5%90%8D%E8%BD%AF%E4%BB%B6/index.html&pic=&searchPic=false&style=simple" target="_blank">
            <li class="mdl-menu__item">
                分享到微博
            </li>
        </a>
    

    <!-- Share Twitter -->
    
        <a class="post_share-link" href="https://twitter.com/intent/tweet?text=用Python做了一个点名软件&url=https://doushabao_233.gitee.io//2023/03/17/%E7%94%A8Python%E5%81%9A%E4%BA%86%E4%B8%80%E4%B8%AA%E7%82%B9%E5%90%8D%E8%BD%AF%E4%BB%B6/index.html&via=Doushabao" target="_blank">
            <li class="mdl-menu__item">
                分享到 Twitter
            </li>
        </a>
    

    <!-- Share Facebook -->
    
        <a class="post_share-link" href="https://www.facebook.com/sharer/sharer.php?u=https://doushabao_233.gitee.io//2023/03/17/%E7%94%A8Python%E5%81%9A%E4%BA%86%E4%B8%80%E4%B8%AA%E7%82%B9%E5%90%8D%E8%BD%AF%E4%BB%B6/index.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Facebook
            </li>
        </a>
    

    <!-- Share Google+ -->
    
        <a class="post_share-link" href="https://plus.google.com/share?url=https://doushabao_233.gitee.io//2023/03/17/%E7%94%A8Python%E5%81%9A%E4%BA%86%E4%B8%80%E4%B8%AA%E7%82%B9%E5%90%8D%E8%BD%AF%E4%BB%B6/index.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Google+
            </li>
        </a>
    

    <!-- Share LinkedIn -->
    

    <!-- Share QQ -->
    

    <!-- Share Telegram -->
    
</ul>

</div>

                

                <!-- Post Content -->
                <div id="post-content" class="markdown-Github mdl-color-text--grey-700 mdl-card__supporting-text fade out">
    
        <h1 id="起因…"><a href="#起因…" class="headerlink" title="起因…"></a>起因…</h1><p>最近，我突然萌生出给班里做一个点名软件的想法。正巧，我有一些计算机编程基础，曾经设计过一些垃圾软件，我觉得我可以试一试。</p>
<h1 id="前排提醒"><a href="#前排提醒" class="headerlink" title="前排提醒"></a>前排提醒</h1><p>我的代码有借鉴百度上的，多线程函数（<code>thread_it</code>）就是。</p>
<p>这些记录是我根据我的记忆复盘出来的，并不是每一次修改的版本我都有，我尽力将每个版本复盘出来。</p>
<h1 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h1><p>既然要做一个点名器，那我们来分析分析它大概的步骤。</p>
<p>需要软件&#x2F;工具：</p>
<ul>
<li>Python - 编程语言</li>
<li>Tkinter - Python的GUI编程库</li>
<li>Pyinstaller - 将Python程序打包成.exe文件</li>
<li>threading - Python多线程库</li>
<li>Pyttsx3 - Python文字转语音</li>
</ul>
<p>这里，Python是编程语言自然不用多说；选用Tkinter是因为本废物只会用这一个了；用Pyinstaller将程序打包为exe，可以直接拷贝到学校电脑上用；threading到底有什么用，我们后面再讲。</p>
<p>然后，我们可能需要实现这些功能：</p>
<ol>
<li>程序打开后显示“点名器”</li>
<li>点击下面按钮开始随机点名，屏幕上的名字会一直随机显示</li>
<li>再点一次按钮（或等待几秒钟后）停止变化。</li>
<li>如果能把名字加粗显示，或者朗读出来，自然是最好的。</li>
</ol>
<h1 id="编程"><a href="#编程" class="headerlink" title="编程"></a>编程</h1><p>说干就干，于是我<del>马上去旧的代码里抄出来一段代码</del>，并经过缝缝补补，大致把框架写出来了：</p>
<p><img src="https://s2.loli.net/2023/03/17/r1LGijo6ctbenyP.png" alt="image.png"></p>
<p>还不错，是吧。上面的菜单栏…不好意思，复制下来的，时间紧迫，先放在那好了。</p>
<p>现在，按钮、菜单栏还没有被赋予实际功能，那么接下来，我们就需要让上面的Label随机闪烁名字。</p>
<p>首先，既然是点名器，那就不能蠢呼呼的把所有姓名都硬编码到源代码里，这样，程序拿到别人手里就不能用了。所以我们要从TXT里读取内容。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;人名单.txt&#x27;</span>, <span class="string">&#x27;r&#x27;</span>, encoding=<span class="string">&#x27;u8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;read file!&#x27;</span>)</span><br><span class="line">        name_list = [i.strip() <span class="keyword">for</span> i <span class="keyword">in</span> f.readlines()]</span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;oh no, we have an error!&#x27;</span>)</span><br><span class="line">    msgbox.showerror(<span class="string">&#x27;找不到文件！&#x27;</span>, <span class="string">&#x27;需要人名单.txt才可以使用&#x27;</span>)</span><br><span class="line">    msgbox.showerror(<span class="string">&#x27;debug&#x27;</span>, <span class="string">&#x27;错误是&#123;&#125;&#x27;</span>.<span class="built_in">format</span>(e))</span><br><span class="line">    exit()</span><br></pre></td></tr></table></figure>

<p>（<code>exit</code>函数是从 <code>sys</code>库导入的，<code>msgbox</code>是从 <code>tkinter.messagebox</code>导入并且改了名字。）</p>
<p>人名单存到 <code>name_list</code>里。</p>
<p>现在就可以读取人名单里的名字了。运行程序，如果目录下有文件的话，那么他会输出：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">read file!</span><br></pre></td></tr></table></figure>

<p>work！继续下一步吧。</p>
<p>我们定义一个 <code>tkinter</code>里的 <code>StringVar</code>（字符串变量），这个时候就有聪明的小伙伴问了：Python不是有字符串吗？用这个干嘛？因为这个更改按钮、文字……这些能显示字的窗口控件的文本内容，也就是说，我们的设想里不是说点一下开始，再点一下结束吗？那怎么更改按钮显示的这个“开始”“结束”就用 <code>StringVar</code>改。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">button_text = StringVar()</span><br><span class="line">button_text.<span class="built_in">set</span>(<span class="string">&#x27;开始&#x27;</span>)</span><br></pre></td></tr></table></figure>

<p>程序开始的时候是“开始”，点一下变为“结束”，意思是再点一下停止点名。</p>
<p>然后写一个函数叫 <code>dice</code>，点击点名按钮开始执行这个函数，这个函数可以随机点名，还要更改按钮的文字。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">dice</span>(): <span class="comment"># 随机点名</span></span><br><span class="line">    <span class="keyword">if</span> (button_text.get() == <span class="string">&#x27;开始&#x27;</span>): <span class="comment"># 开始点名</span></span><br><span class="line">        title.config(foreground=<span class="string">&#x27;black&#x27;</span>, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">40</span>)) <span class="comment"># 把名字字体设为40号</span></span><br><span class="line">        button_text.<span class="built_in">set</span>(<span class="string">&#x27;结束&#x27;</span>)</span><br><span class="line">        <span class="keyword">while</span> <span class="number">1</span>:</span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&#x27;change!&#x27;</span>, name_list[idx]) <span class="comment"># 不用管，调试用的</span></span><br><span class="line">            random_name.<span class="built_in">set</span>(name_list[idx]) <span class="comment"># 选择好名字后展示到窗口上</span></span><br><span class="line">            time.sleep(<span class="number">0.07</span>) <span class="comment"># 每次切换等0.07秒</span></span><br><span class="line">    <span class="keyword">else</span>: <span class="comment"># 如果按钮文本不是“开始”，那不就得结束点名</span></span><br><span class="line">        button_text.<span class="built_in">set</span>(<span class="string">&#x27;开始&#x27;</span>) <span class="comment"># 把按钮文字改回去</span></span><br></pre></td></tr></table></figure>

<p>可是……这样<strong>问题很大</strong>，怎么说呢，给大家画个流程图吧。</p>
<p><img src="https://s2.loli.net/2023/03/17/G2ytZ1oCqsl4khQ.png" alt="image.png"></p>
<p>按钮按下后，窗口会永远等待着函数执行完，这是不可改变的，函数执行不完，Windows系统就开始不耐烦了：未响应……于是，这就陷入了死局，你停不下来这个循环，这个循环就无法结束，就在这里卡着。</p>
<p>那么，别让等待成为遗憾！！！没错，终于要用到 <code>threading</code>模块了！为什么不更改一下策略呢？像这样：</p>
<p><img src="https://s2.loli.net/2023/03/17/l2XCLdcVrqQKoGx.png" alt="image.png"></p>
<p>现在点击了按钮，就会开一个新的<strong>线程</strong>出来，大家各干各的，不会占着茅坑不拉屎了。那，落实到代码上：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">thread_it</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;将函数打包进线程 不会让主界面卡死&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="comment"># 创建</span></span><br><span class="line">    t = threading.Thread(target=func) </span><br><span class="line">    <span class="comment"># 守护 !!!</span></span><br><span class="line">    t.daemon = <span class="literal">True</span></span><br><span class="line">    <span class="comment"># 启动</span></span><br><span class="line">    t.start()</span><br><span class="line">    <span class="comment"># 阻塞--卡死界面！</span></span><br><span class="line">    <span class="comment"># t.join()</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">dice</span>(): <span class="comment"># 随机点名</span></span><br><span class="line">    <span class="keyword">global</span> IWannaExit</span><br><span class="line">    <span class="keyword">if</span> (button_text.get() == <span class="string">&#x27;开始&#x27;</span>): <span class="comment"># 开始点名</span></span><br><span class="line">        title.config(foreground=<span class="string">&#x27;black&#x27;</span>, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">40</span>)) <span class="comment"># 把名字字体设为40号</span></span><br><span class="line">        button_text.<span class="built_in">set</span>(<span class="string">&#x27;结束&#x27;</span>)</span><br><span class="line">        <span class="keyword">while</span> <span class="number">1</span>: <span class="comment"># 死循环，但是有退出条件在下面</span></span><br><span class="line">            <span class="keyword">if</span> IWannaExit: <span class="comment"># 如果结束循环了，那么执行这些，否则不会执行</span></span><br><span class="line">                IWannaExit = <span class="literal">False</span> </span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&#x27;stop!&#x27;</span>)</span><br><span class="line">                title.config(foreground=<span class="string">&#x27;black&#x27;</span>, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">40</span>, <span class="string">&#x27;bold&#x27;</span>)) <span class="comment"># …那么把名字改成粗体</span></span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">            random_name.<span class="built_in">set</span>(random.choice(name_list)) <span class="comment"># 选择好名字后展示到窗口上</span></span><br><span class="line">            time.sleep(<span class="number">0.07</span>) <span class="comment"># 每次切换等0.07秒</span></span><br><span class="line">    <span class="keyword">else</span>: <span class="comment"># 结束点名</span></span><br><span class="line">        button_text.<span class="built_in">set</span>(<span class="string">&#x27;开始&#x27;</span>) <span class="comment"># 把按钮文字改回去</span></span><br><span class="line">        IWannaExit = <span class="literal">True</span> <span class="comment"># 用这个通知它停止点名</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>现在，运行程序就不会卡住了，按照流程图的过程运行，到这里，点名器已经可以用啦。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Python lib require: pip install pyttsx3</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># import json</span></span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="comment"># import hashlib</span></span><br><span class="line"><span class="keyword">import</span> threading, time</span><br><span class="line"><span class="keyword">from</span> sys <span class="keyword">import</span> exit</span><br><span class="line"><span class="keyword">import</span> tkinter.messagebox <span class="keyword">as</span> msgbox</span><br><span class="line"><span class="keyword">from</span> tkinter <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> tkinter.ttk <span class="keyword">import</span> *</span><br><span class="line">IWannaExit = <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;人名单.txt&#x27;</span>, <span class="string">&#x27;r&#x27;</span>, encoding=<span class="string">&#x27;u8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;read file!&#x27;</span>)</span><br><span class="line">        name_list = [i.strip() <span class="keyword">for</span> i <span class="keyword">in</span> f.readlines()]</span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;oh no, we have an error!&#x27;</span>)</span><br><span class="line">    msgbox.showerror(<span class="string">&#x27;找不到文件！&#x27;</span>, <span class="string">&#x27;需要人名单.txt才可以使用&#x27;</span>)</span><br><span class="line">    msgbox.showerror(<span class="string">&#x27;debug&#x27;</span>, <span class="string">&#x27;错误是&#123;&#125;&#x27;</span>.<span class="built_in">format</span>(e))</span><br><span class="line">    exit()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">thread_it</span>(<span class="params">func</span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;将函数打包进线程 不会让主界面卡死&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="comment"># 创建</span></span><br><span class="line">    t = threading.Thread(target=func) </span><br><span class="line">    <span class="comment"># 守护 !!!</span></span><br><span class="line">    t.daemon = <span class="literal">True</span></span><br><span class="line">    <span class="comment"># 启动</span></span><br><span class="line">    t.start()</span><br><span class="line">    <span class="comment"># 阻塞--卡死界面！</span></span><br><span class="line">    <span class="comment"># t.join()</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">dice</span>(): <span class="comment"># 随机点名</span></span><br><span class="line">    <span class="keyword">global</span> IWannaExit</span><br><span class="line">    <span class="keyword">if</span> (button_text.get() == <span class="string">&#x27;开始&#x27;</span>): <span class="comment"># 开始点名</span></span><br><span class="line">        title.config(foreground=<span class="string">&#x27;black&#x27;</span>, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">40</span>)) <span class="comment"># 把名字字体设为40号</span></span><br><span class="line">        button_text.<span class="built_in">set</span>(<span class="string">&#x27;结束&#x27;</span>)</span><br><span class="line">        <span class="keyword">while</span> <span class="number">1</span>: <span class="comment"># 死循环，但是有退出条件在下面</span></span><br><span class="line">            <span class="keyword">if</span> IWannaExit: <span class="comment"># 如果结束循环了，那么执行这些，否则不会执行</span></span><br><span class="line">                IWannaExit = <span class="literal">False</span> </span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&#x27;stop!&#x27;</span>)</span><br><span class="line">                title.config(foreground=<span class="string">&#x27;black&#x27;</span>, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">40</span>, <span class="string">&#x27;bold&#x27;</span>)) <span class="comment"># …那么把名字改成粗体</span></span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">            random_name.<span class="built_in">set</span>(random.choice(name_list)) <span class="comment"># 选择好名字后展示到窗口上</span></span><br><span class="line">            time.sleep(<span class="number">0.07</span>) <span class="comment"># 每次切换等0.07秒</span></span><br><span class="line">    <span class="keyword">else</span>: <span class="comment"># 结束点名</span></span><br><span class="line">        button_text.<span class="built_in">set</span>(<span class="string">&#x27;开始&#x27;</span>) <span class="comment"># 把按钮文字改回去</span></span><br><span class="line">        IWannaExit = <span class="literal">True</span> <span class="comment"># 用这个通知它停止点名</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;init window!&#x27;</span>)</span><br><span class="line"></span><br><span class="line">window = Tk() <span class="comment"># 初始化窗口</span></span><br><span class="line">window.title(<span class="string">&#x27;点名器&#x27;</span>) <span class="comment"># 这是标题</span></span><br><span class="line">window.resizable(<span class="literal">False</span>, <span class="literal">False</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;prepare variables!&#x27;</span>)</span><br><span class="line"></span><br><span class="line">random_name = StringVar()</span><br><span class="line">random_name.<span class="built_in">set</span>(<span class="string">&#x27;点名器&#x27;</span>)</span><br><span class="line">button_text = StringVar()</span><br><span class="line">button_text.<span class="built_in">set</span>(<span class="string">&#x27;开始&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建菜单栏</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">about</span>():</span><br><span class="line">    msgbox.showinfo(</span><br><span class="line">        <span class="string">&#x27;关于&#x27;</span>, </span><br><span class="line">        <span class="string">&#x27;&#x27;</span></span><br><span class="line">)</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">version</span>():</span><br><span class="line">    msgbox.showinfo(<span class="string">&#x27;版本&#x27;</span>, <span class="string">&#x27;v1.0（还不知道写啥）&#x27;</span>)</span><br><span class="line"></span><br><span class="line">menubar = Menu(window) <span class="comment"># 也是创建菜单栏</span></span><br><span class="line">menu_help = Menu(menubar, tearoff=<span class="number">0</span>)</span><br><span class="line">menubar.add_cascade(label=<span class="string">&#x27;帮助&#x27;</span>, menu=menu_help)</span><br><span class="line">menu_help.add_command(label=<span class="string">&#x27;关于&#x27;</span>, command=about)</span><br><span class="line">menu_help.add_command(label=<span class="string">&#x27;版本&#x27;</span>, command=version)</span><br><span class="line">window.config(menu=menubar)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;define things!&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义标题</span></span><br><span class="line">title = Label(window, text=<span class="string">&#x27;点名器&#x27;</span>, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">40</span>), textvariable=random_name)</span><br><span class="line">title.grid(row=<span class="number">1</span>, column=<span class="number">1</span>, padx=<span class="number">15</span>, pady=<span class="number">15</span>) <span class="comment"># 把标题放在对应位置</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义下面的提示</span></span><br><span class="line">tips = Label(text=<span class="string">&#x27;点击按钮开始随机点名&#x27;</span>, font=(<span class="string">&#x27;等线&#x27;</span>, <span class="number">20</span>))</span><br><span class="line">tips.grid(row=<span class="number">2</span>, column=<span class="number">1</span>, padx=<span class="number">15</span>, pady=<span class="number">15</span>) <span class="comment"># 把提示放在对应位置</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 定义按钮</span></span><br><span class="line">start_rolling = Button(text=<span class="string">&#x27;开始&#x27;</span>, width=<span class="number">43</span>, command=<span class="keyword">lambda</span>: thread_it(dice), textvariable=button_text)</span><br><span class="line">start_rolling.grid(row=<span class="number">4</span>, column=<span class="number">1</span>, padx=<span class="number">15</span>, pady=<span class="number">15</span>) <span class="comment"># 把按钮放在对应位置</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;okay, hello world!&#x27;</span>)</span><br><span class="line">window.mainloop() <span class="comment"># 窗口主循环。</span></span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h1 id="还是不够过瘾"><a href="#还是不够过瘾" class="headerlink" title="还是不够过瘾"></a>还是不够过瘾</h1><p>都到这份上了，不再锦上添花一下，我是不乐意的。</p>
<p>于是，我给他整了个<strong>朗读功能</strong>。</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">engine = pyttsx3.init() <span class="comment"># 初始化文字朗读引擎</span></span><br><span class="line"></span><br><span class="line">engine.setProperty(<span class="string">&#x27;rate&#x27;</span>, <span class="number">150</span>) <span class="comment"># 设置语速为1.5x最合适</span></span><br><span class="line">engine.setProperty(<span class="string">&#x27;volume&#x27;</span>, <span class="number">2</span>) <span class="comment"># 设置音量为2</span></span><br><span class="line"></span><br><span class="line">voices = engine.getProperty(<span class="string">&#x27;voices&#x27;</span>) <span class="comment"># 获取系统里所有文字朗读模型</span></span><br><span class="line">engine.setProperty(<span class="string">&#x27;voice&#x27;</span>,voices[<span class="number">0</span>].<span class="built_in">id</span>) <span class="comment"># 选取第一个（中文）</span></span><br></pre></td></tr></table></figure>

<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">thread_it(say, random.choice(name_list))</span><br></pre></td></tr></table></figure>

<p>然后，历史记录：</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">history_window</span>():</span><br><span class="line"></span><br><span class="line">    window = Tk()</span><br><span class="line">    window.title(<span class="string">&#x27;历史记录&#x27;</span>)</span><br><span class="line">    window.iconbitmap(<span class="string">&#x27;favicon.ico&#x27;</span>)</span><br><span class="line">  </span><br><span class="line">    <span class="comment"># 告诉操作系统使用程序自身的dpi适配</span></span><br><span class="line">    ctypes.windll.shcore.SetProcessDpiAwareness(<span class="number">1</span>)</span><br><span class="line">    <span class="comment"># 获取屏幕的缩放因子</span></span><br><span class="line">    ScaleFactor=ctypes.windll.shcore.GetScaleFactorForDevice(<span class="number">0</span>)</span><br><span class="line">    <span class="comment"># 设置程序缩放</span></span><br><span class="line">    window.call(<span class="string">&#x27;tk&#x27;</span>, <span class="string">&#x27;scaling&#x27;</span>, ScaleFactor / <span class="number">75</span>)</span><br><span class="line"></span><br><span class="line">    history_listbox = Listbox(window, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">20</span>))</span><br><span class="line">    history_listbox.grid(row=<span class="number">0</span>, column=<span class="number">0</span>, padx=<span class="number">10</span>, pady=<span class="number">10</span>)</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">update_history</span>():</span><br><span class="line">        <span class="keyword">while</span> <span class="number">1</span>:</span><br><span class="line">            time.sleep(<span class="number">0.4</span>)</span><br><span class="line">            <span class="keyword">try</span>:</span><br><span class="line">                history_listbox.delete(<span class="number">0</span>, <span class="string">&#x27;end&#x27;</span>)</span><br><span class="line">            <span class="keyword">except</span>:</span><br><span class="line">                <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">            <span class="keyword">for</span> item <span class="keyword">in</span> history:</span><br><span class="line">                <span class="keyword">try</span>:</span><br><span class="line">                    history_listbox.insert(<span class="string">&#x27;end&#x27;</span>, item)</span><br><span class="line">                <span class="keyword">except</span>:</span><br><span class="line">                    <span class="keyword">pass</span></span><br><span class="line">    thread_it(update_history)</span><br><span class="line"></span><br><span class="line">    window.mainloop()</span><br></pre></td></tr></table></figure>

<p><img src="https://s2.loli.net/2023/03/18/aeNZwsnogUvmpD7.png" alt="image.png"></p>
<p><strong>置顶窗口：</strong></p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">go_top</span>():</span><br><span class="line">    <span class="keyword">nonlocal</span> on_top</span><br><span class="line">    <span class="keyword">if</span> on_top:</span><br><span class="line">        window.wm_attributes(<span class="string">&#x27;-topmost&#x27;</span>, <span class="number">0</span>)</span><br><span class="line">        on_top = <span class="literal">False</span></span><br><span class="line">        menu.entryconfigure(<span class="number">0</span>, &#123;<span class="string">&#x27;label&#x27;</span>: <span class="string">&#x27;置顶模式&#x27;</span>&#125;)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        window.wm_attributes(<span class="string">&#x27;-topmost&#x27;</span>, <span class="number">1</span>)</span><br><span class="line">        on_top = <span class="literal">True</span></span><br><span class="line">        menu.entryconfigure(<span class="number">0</span>, &#123;<span class="string">&#x27;label&#x27;</span>: <span class="string">&#x27;置顶模式 √&#x27;</span>&#125;)</span><br></pre></td></tr></table></figure>

<h1 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h1><p>暂时懒得开源GitHub。如果你有建议的话，直接跟我说吧。</p>
<p>目前代码还有些屎山，不过，能用就行……（哭笑</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># pip install pyttsx3</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># import json</span></span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="comment"># import hashlib</span></span><br><span class="line"><span class="keyword">import</span> threading, time, pyttsx3, ctypes</span><br><span class="line"><span class="keyword">from</span> sys <span class="keyword">import</span> exit</span><br><span class="line"><span class="keyword">import</span> tkinter.messagebox <span class="keyword">as</span> msgbox</span><br><span class="line"><span class="keyword">from</span> tkinter <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> tkinter.ttk <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;define tts engine!&#x27;</span>)</span><br><span class="line"></span><br><span class="line">engine = pyttsx3.init() <span class="comment"># 初始化文字朗读引擎</span></span><br><span class="line"></span><br><span class="line">engine.setProperty(<span class="string">&#x27;rate&#x27;</span>, <span class="number">150</span>) <span class="comment"># 设置语速为1.5x最合适</span></span><br><span class="line">engine.setProperty(<span class="string">&#x27;volume&#x27;</span>, <span class="number">2</span>) <span class="comment"># 设置音量为2</span></span><br><span class="line"></span><br><span class="line">voices = engine.getProperty(<span class="string">&#x27;voices&#x27;</span>) <span class="comment"># 获取系统里所有文字朗读模型</span></span><br><span class="line">engine.setProperty(<span class="string">&#x27;voice&#x27;</span>,voices[<span class="number">0</span>].<span class="built_in">id</span>) <span class="comment"># 选取第一个（中文）</span></span><br><span class="line"></span><br><span class="line">history = [] <span class="comment"># 历史记录</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;人名单.txt&#x27;</span>, <span class="string">&#x27;r&#x27;</span>, encoding=<span class="string">&#x27;u8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;read file!&#x27;</span>)</span><br><span class="line">        name_list = [i.strip() <span class="keyword">for</span> i <span class="keyword">in</span> f.readlines()]</span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;oh no, we have an error!&#x27;</span>)</span><br><span class="line">    msgbox.showerror(<span class="string">&#x27;找不到文件！&#x27;</span>, <span class="string">&#x27;需要人名单.txt才可以使用&#x27;</span>)</span><br><span class="line">    msgbox.showerror(<span class="string">&#x27;debug&#x27;</span>, <span class="string">&#x27;错误是&#123;&#125;&#x27;</span>.<span class="built_in">format</span>(e))</span><br><span class="line">    exit()</span><br><span class="line"></span><br><span class="line">idx = random.randint(<span class="number">0</span>, <span class="built_in">len</span>(name_list) - <span class="number">1</span>) <span class="comment"># 随机选择一个数字</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">thread_it</span>(<span class="params">func, *args: <span class="built_in">tuple</span></span>):</span><br><span class="line">    <span class="string">&#x27;&#x27;&#x27;将函数打包进线程 不会让主界面卡死&#x27;&#x27;&#x27;</span></span><br><span class="line">    <span class="comment"># 创建</span></span><br><span class="line">    t = threading.Thread(target=func, args=args) </span><br><span class="line">    t.daemon = <span class="literal">True</span></span><br><span class="line">    t.start()</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">say</span>(<span class="params">text: <span class="built_in">str</span></span>):</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        engine.say(text) <span class="comment"># 朗读抽到的名字</span></span><br><span class="line">        engine.runAndWait()</span><br><span class="line">        engine.stop()</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;speak&#x27;</span>, text)</span><br><span class="line">    <span class="keyword">except</span> RuntimeError <span class="keyword">as</span> e:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;error catched!&#x27;</span>, e)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">history_window</span>():</span><br><span class="line">          </span><br><span class="line">    <span class="comment"># global history_listbox # 允许这个UI列表被其他函数操控，没错就是给dice准备的</span></span><br><span class="line"></span><br><span class="line">    window = Tk()</span><br><span class="line">    window.title(<span class="string">&#x27;历史记录&#x27;</span>)</span><br><span class="line">    window.iconbitmap(<span class="string">&#x27;favicon.ico&#x27;</span>)</span><br><span class="line">  </span><br><span class="line">    <span class="comment"># 告诉操作系统使用程序自身的dpi适配</span></span><br><span class="line">    ctypes.windll.shcore.SetProcessDpiAwareness(<span class="number">1</span>)</span><br><span class="line">    <span class="comment"># 获取屏幕的缩放因子</span></span><br><span class="line">    ScaleFactor=ctypes.windll.shcore.GetScaleFactorForDevice(<span class="number">0</span>)</span><br><span class="line">    <span class="comment"># 设置程序缩放</span></span><br><span class="line">    window.call(<span class="string">&#x27;tk&#x27;</span>, <span class="string">&#x27;scaling&#x27;</span>, ScaleFactor / <span class="number">75</span>)</span><br><span class="line"></span><br><span class="line">    history_listbox = Listbox(window, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">20</span>))</span><br><span class="line">    history_listbox.grid(row=<span class="number">0</span>, column=<span class="number">0</span>, padx=<span class="number">10</span>, pady=<span class="number">10</span>)</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">update_history</span>():</span><br><span class="line">        <span class="keyword">while</span> <span class="number">1</span>:</span><br><span class="line">            time.sleep(<span class="number">0.4</span>)</span><br><span class="line">            <span class="keyword">try</span>:</span><br><span class="line">                history_listbox.delete(<span class="number">0</span>, <span class="string">&#x27;end&#x27;</span>)</span><br><span class="line">            <span class="keyword">except</span>:</span><br><span class="line">                <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line">            <span class="keyword">for</span> item <span class="keyword">in</span> history:</span><br><span class="line">                <span class="keyword">try</span>:</span><br><span class="line">                    history_listbox.insert(<span class="string">&#x27;end&#x27;</span>, item)</span><br><span class="line">                <span class="keyword">except</span>:</span><br><span class="line">                    <span class="keyword">pass</span></span><br><span class="line">    thread_it(update_history)</span><br><span class="line"></span><br><span class="line">    window.mainloop()</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">main_window</span>():</span><br><span class="line">    IWannaExit = <span class="literal">False</span></span><br><span class="line">    on_top = <span class="literal">False</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">dice</span>(): <span class="comment"># 随机点名</span></span><br><span class="line">        <span class="keyword">global</span> idx</span><br><span class="line">        <span class="keyword">nonlocal</span> IWannaExit</span><br><span class="line">        <span class="keyword">if</span> (button_text.get() == <span class="string">&#x27;开始&#x27;</span>): <span class="comment"># 开始点名</span></span><br><span class="line">            title.config(foreground=<span class="string">&#x27;black&#x27;</span>, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">40</span>)) <span class="comment"># 把名字字体设为40号</span></span><br><span class="line">            button_text.<span class="built_in">set</span>(<span class="string">&#x27;结束&#x27;</span>)</span><br><span class="line">            <span class="keyword">while</span> <span class="number">1</span>: <span class="comment"># 死循环，但是有退出条件在下面</span></span><br><span class="line">                start_rolling[<span class="string">&#x27;state&#x27;</span>] = NORMAL <span class="comment"># 允许按钮点击</span></span><br><span class="line">                <span class="keyword">if</span> IWannaExit: <span class="comment"># 如果结束循环了，那么执行这些，否则不会执行</span></span><br><span class="line">                    IWannaExit = <span class="literal">False</span> <span class="comment"># “我”已经要退出了，所以我先设置这个变量为不退出。</span></span><br><span class="line">                    <span class="built_in">print</span>(<span class="string">&#x27;stop!&#x27;</span>, name_list[idx]) <span class="comment"># “我”退出之前，需要处理善后工作。</span></span><br><span class="line">                    title.config(foreground=<span class="string">&#x27;black&#x27;</span>, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">40</span>, <span class="string">&#x27;bold&#x27;</span>)) <span class="comment"># …那么把名字改成粗体</span></span><br><span class="line">                    history.append(name_list[idx]) <span class="comment"># 历史记录</span></span><br><span class="line">                    thread_it(say, (name_list[idx]))</span><br><span class="line">                    <span class="keyword">break</span> <span class="comment"># 退出</span></span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&#x27;change!&#x27;</span>, name_list[idx]) <span class="comment"># 不用管，调试用的</span></span><br><span class="line">                idx = (idx + <span class="number">1</span>) % <span class="built_in">len</span>(name_list) <span class="comment"># 按顺序从左到右选，据说这样不容易重复</span></span><br><span class="line">                random_name.<span class="built_in">set</span>(name_list[idx]) <span class="comment"># 选择好名字后展示到窗口上</span></span><br><span class="line">                time.sleep(<span class="number">0.07</span>) <span class="comment"># 每次切换等0.07秒</span></span><br><span class="line">        <span class="keyword">else</span>: <span class="comment"># 结束点名</span></span><br><span class="line">            button_text.<span class="built_in">set</span>(<span class="string">&#x27;开始&#x27;</span>) <span class="comment"># 把按钮文字改回去</span></span><br><span class="line">            IWannaExit = <span class="literal">True</span> <span class="comment"># 用这个通知它停止点名</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">  </span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;init window!&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    window = Tk() <span class="comment"># 初始化窗口</span></span><br><span class="line">    window.title(<span class="string">&#x27;点名器&#x27;</span>) <span class="comment"># 这是标题</span></span><br><span class="line">    window.resizable(<span class="literal">False</span>, <span class="literal">False</span>)</span><br><span class="line">    window.iconbitmap(<span class="string">&#x27;favicon.ico&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 告诉操作系统使用程序自身的dpi适配</span></span><br><span class="line">    ctypes.windll.shcore.SetProcessDpiAwareness(<span class="number">1</span>)</span><br><span class="line">    <span class="comment"># 获取屏幕的缩放因子</span></span><br><span class="line">    ScaleFactor=ctypes.windll.shcore.GetScaleFactorForDevice(<span class="number">0</span>)</span><br><span class="line">    <span class="comment"># 设置程序缩放</span></span><br><span class="line">    window.call(<span class="string">&#x27;tk&#x27;</span>, <span class="string">&#x27;scaling&#x27;</span>, ScaleFactor / <span class="number">75</span>)</span><br><span class="line"></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;prepare variables!&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    random_name = StringVar()</span><br><span class="line">    random_name.<span class="built_in">set</span>(<span class="string">&#x27;点名器&#x27;</span>)</span><br><span class="line">    button_text = StringVar()</span><br><span class="line">    button_text.<span class="built_in">set</span>(<span class="string">&#x27;开始&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 创建菜单栏</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">go_top</span>():</span><br><span class="line">        <span class="keyword">nonlocal</span> on_top</span><br><span class="line">        <span class="keyword">if</span> on_top:</span><br><span class="line">            window.wm_attributes(<span class="string">&#x27;-topmost&#x27;</span>, <span class="number">0</span>)</span><br><span class="line">            on_top = <span class="literal">False</span></span><br><span class="line">            menu.entryconfigure(<span class="number">0</span>, &#123;<span class="string">&#x27;label&#x27;</span>: <span class="string">&#x27;置顶模式&#x27;</span>&#125;)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            window.wm_attributes(<span class="string">&#x27;-topmost&#x27;</span>, <span class="number">1</span>)</span><br><span class="line">            on_top = <span class="literal">True</span></span><br><span class="line">            menu.entryconfigure(<span class="number">0</span>, &#123;<span class="string">&#x27;label&#x27;</span>: <span class="string">&#x27;置顶模式 √&#x27;</span>&#125;)</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">version</span>():</span><br><span class="line">        msgbox.showinfo(<span class="string">&#x27;版本&#x27;</span>, <span class="string">&#x27;v1.2 更新：\n1. 调整了窗口大小，现在变的更紧凑了；\n2. 加入了历史记录，可以查看之前随机到的名字；\n3. 新增了置顶窗口选项，一边讲PPT一边用它两不误。&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    menubar = Menu(window) <span class="comment"># 也是创建菜单栏</span></span><br><span class="line">    menu = Menu(menubar, tearoff=<span class="literal">False</span>)</span><br><span class="line">    menubar.add_cascade(label=<span class="string">&#x27;菜单&#x27;</span>, menu=menu)</span><br><span class="line">    menu.add_command(label=<span class="string">&#x27;置顶模式&#x27;</span>, command=go_top)</span><br><span class="line">    menu.add_command(label=<span class="string">&#x27;版本&#x27;</span>, command=version)</span><br><span class="line">    window.config(menu=menubar)</span><br><span class="line"></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;define things!&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 定义标题</span></span><br><span class="line">    title = Label(window, text=<span class="string">&#x27;点名器&#x27;</span>, font=(<span class="string">&#x27;微软雅黑&#x27;</span>, <span class="number">40</span>), textvariable=random_name)</span><br><span class="line">    title.grid(row=<span class="number">1</span>, column=<span class="number">1</span>, padx=<span class="number">15</span>, pady=<span class="number">15</span>) <span class="comment"># 把标题放在对应位置</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 定义下面的提示</span></span><br><span class="line">    <span class="comment"># tips = Label(text=&#x27;点击按钮开始随机点名&#x27;, font=(&#x27;等线&#x27;, 20))</span></span><br><span class="line">    <span class="comment"># tips.grid(row=2, column=1, padx=15, pady=15) # 把提示放在对应位置</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># 定义按钮</span></span><br><span class="line">    start_rolling = Button(text=<span class="string">&#x27;开始&#x27;</span>, width=<span class="number">35</span>, command=<span class="keyword">lambda</span>: thread_it(dice), textvariable=button_text)</span><br><span class="line">    start_rolling.grid(row=<span class="number">4</span>, column=<span class="number">1</span>, padx=<span class="number">15</span>, pady=<span class="number">5</span>) <span class="comment"># 把按钮放在对应位置</span></span><br><span class="line">  </span><br><span class="line">    history_button = Button(text=<span class="string">&#x27;历史记录&#x27;</span>, width=<span class="number">35</span>, command=history_window)</span><br><span class="line">    history_button.grid(row=<span class="number">5</span>, column=<span class="number">1</span>, padx=<span class="number">15</span>, pady=<span class="number">15</span>) <span class="comment"># 把按钮放在对应位置</span></span><br><span class="line">  </span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;okay, hello world!&#x27;</span>)</span><br><span class="line"></span><br><span class="line">main_window()</span><br><span class="line">mainloop() <span class="comment"># 所有窗口主循环。</span></span><br></pre></td></tr></table></figure>

    

    
</div>


                

                <!-- Post Comments -->
                
                    



                
            </div>

            <!-- Post Prev & Next Nav -->
            <nav class="material-nav mdl-color-text--grey-50 mdl-cell mdl-cell--12-col">
    <!-- Prev Nav -->
    
        <a href="/2023/05/10/模组开发日记 一/" id="post_nav-newer" class="prev-content">
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_back</i>
            </button>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            新篇
        </a>
    

    <!-- Section Spacer -->
    <div class="section-spacer"></div>

    <!-- Next Nav -->
    
        <a href="/2023/03/02/豆沙包的第一篇文章/" id="post_nav-older" class="next-content">
            旧篇
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_forward</i>
            </button>
        </a>
    
</nav>

        </div>
    </div>



                    
                        <!-- Overlay For Active Sidebar -->
<div class="sidebar-overlay"></div>

<!-- Material sidebar -->
<aside id="sidebar" class="sidebar sidebar-colored sidebar-fixed-left" role="navigation">
    <div id="sidebar-main">
        <!-- Sidebar Header -->
        <div class="sidebar-header header-cover" style="background-image: url(/img/sidebar_header.png);">
    <!-- Top bar -->
    <div class="top-bar"></div>

    <!-- Sidebar toggle button -->
    <button type="button" class="sidebar-toggle mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon" style="display: initial;" data-upgraded=",MaterialButton,MaterialRipple">
        <i class="material-icons">clear_all</i>
        <span class="mdl-button__ripple-container">
            <span class="mdl-ripple">
            </span>
        </span>
    </button>

    <!-- Sidebar Avatar -->
    <div class="sidebar-image">
        <img src="/img/avatar.png" alt="Doushabao's avatar">
    </div>

    <!-- Sidebar Email -->
    <a data-toggle="dropdown" class="sidebar-brand" href="#settings-dropdown">
        onedoushabao@qq.com
        <b class="caret"></b>
    </a>
</div>


        <!-- Sidebar Navigation  -->
        <ul class="nav sidebar-nav">
    <!-- User dropdown  -->
    <li class="dropdown">
        <ul id="settings-dropdown" class="dropdown-menu">
            
                <li>
                    <a href="#" target="_blank" title="Email Me">
                        <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        Email Me
                    </a>
                </li>
            
        </ul>
    </li>

    <!-- Homepage -->
    <li id="sidebar-first-li">
        <a href="/" target="_self">
            <i class="material-icons sidebar-material-icons">home</i>
            主页
        </a>
    </li>

    <!-- I'm Feeling Lucky -->
    <!--
    <li class="dropdown">
        <a href="" target="_self">
            <i class="material-icons sidebar-material-icons">explore</i>
             sidebar.imlucky
        </a>
    </li>
    -->

    <!-- Archives  -->
    <li class="dropdown">
        <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
            <i class="material-icons sidebar-material-icons">inbox</i>
             归档
            <b class="caret"></b>
        </a>
        <ul class="dropdown-menu">
            <li>
            <a class="sidebar_archives-link" href="/archives/2023/05/">五月 2023<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2023/03/">三月 2023<span class="sidebar_archives-count">2</span></a>
        </ul>
    </li>

    <!-- Categories  -->
    

    <!-- Divider -->
    <li class="divider"></li>


    <!-- Pages  -->
  	

    <!-- Article Numebr  -->
    <li>
        <a href="/archives">
            文章总数
            <span class="sidebar-badge">4</span>
        </a>
    </li>
</ul>


        <!-- Sidebar Divider -->
        <div class="sidebar-divider"></div>

        <!-- Sidebar Footer -->
        <!--
I'm glad you use this theme, the development is no so easy, I hope you can keep the copyright, I will thank you so much.
If you still want to delete the copyrights, could you still retain the first one? Which namely "Theme Material"
It will not impact the appearance and can give developers a lot of support :)

很高兴您使用并喜欢该主题，开发不易 十分谢谢与希望您可以保留一下版权声明。
如果您仍然想删除的话 能否只保留第一项呢？即 "Theme Material"
它不会影响美观并可以给开发者很大的支持和动力。 :)
-->

<!-- Theme Material -->
<a href="https://github.com/viosey/hexo-theme-material"  class="sidebar-footer-text-a" target="_blank">
    <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
        主题 - Material
        <span class="sidebar-badge badge-circle">i</span>
    </div>
</a>

<!-- Help & Support -->
<!--
<a href="mailto:hiviosey@gmail.com" class="sidebar-footer-text-a">
    <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
    sidebar.help
    <span class="mdl-button__ripple-container">
      <span class="mdl-ripple"></span>
    </span>
  </div>
</a>
-->

<!-- Feedback -->
<!--
<a href="https://github.com/viosey/hexo-theme-material/issues" target="_blank" class="sidebar-footer-text-a">
    <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
         sidebar.feedback
                    <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></div>
</a>
-->

<!-- Abount Theme -->
<!--
<a href="https://blog.viosey.com/index.php/Material.html" target="_blank" class="sidebar-footer-text-a">
    <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
         sidebar.about_theme
        <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></div>
</a>-->

    </div>

    <!-- Sidebar Sponsor -->
    

</aside>

                    

                    
                        <!-- Footer Top Button -->
                        <div class="toTop-wrap">
    <a href="#top" class="toTop">
        <i class="material-icons footer_top-i">expand_less</i>
    </a>
</div>

                    

                    <!--Footer-->
<footer class="mdl-mini-footer" id="bottom">
    
        <!-- Paradox Footer Left Section -->
        <div class="mdl-mini-footer--left-section sns-list">
    <!-- Twitter -->
    

    <!-- Facebook -->
    

    <!-- Google + -->
    

    <!-- Weibo -->
    

    <!-- Instagram -->
    

    <!-- Tumblr -->
    

    <!-- Github -->
    
        <a href="https://github.com/Doushabao233" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn" style="background-image: url(/img/footer/footer_ico-github.png);">
                <span class="visuallyhidden">Github</span>
            </button><!--
     --></a>
    

    <!-- LinkedIn -->
    

    <!-- Zhihu -->
    

    <!-- Bilibili -->
    
        <a href="https://space.bilibili.com/351258144/" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn" style="background-image: url(/img/footer/footer_ico-bilibili.png);">
                <span class="visuallyhidden">Bilibili</span>
            </button><!--
     --></a>
    

    <!-- Telegram -->
    
</div>


        <!--Copyright-->
        <div id="copyright">
            Copyright&nbsp;©&nbsp;
            <script type="text/javascript">
                var fd = new Date();
                document.write(fd.getFullYear());
            </script>
            &nbsp;豆沙包的博客
        </div>

        <!-- Paradox Footer Right Section -->

        <!--
        I am glad you use this theme, the development is no so easy, I hope you can keep the copyright.
        It will not impact the appearance and can give developers a lot of support :)

        很高兴您使用该主题，开发不易，希望您可以保留一下版权声明。
        它不会影响美观并可以给开发者很大的支持。 :)
        -->

        <div class="mdl-mini-footer--right-section">
            <div>
                <div class="footer-develop-div">Powered by <a href="https://hexo.io" target="_blank" class="footer-develop-a">Hexo</a></div>
                <div class="footer-develop-div">Theme - <a href="https://github.com/viosey/hexo-theme-material" target="_blank" class="footer-develop-a">Material</a></div>
            </div>
        </div>
    
</footer>


                    <!-- Import File -->

<script src="/js/highlight.min.js"></script>


<script src="/js/js.min.js"></script>


<script src="/js/nprogress.js"></script>


<script type="text/javascript">
    NProgress.configure({
        showSpinner: true
    });
    NProgress.start();

    $('#nprogress .bar').css({
        'background': '#FF4081'
    });
    $('#nprogress .peg').css({
        'box-shadow': '0 0 10px #FF4081, 0 0 15px #FF4081'
    });
    $('#nprogress .spinner-icon').css({
        'border-top-color': '#FF4081',
        'border-left-color': '#FF4081'
    });

    setTimeout(function() {
        NProgress.done();
        $('.fade').removeClass('out');
    }, 800);
</script>













<!-- Swiftye -->


<!-- Local Search-->


<!-- Window Load-->
<script>
    $(window).load(function() {
        // Post_Toc parent position fixed
        $('.post-toc-wrap').parent('.mdl-menu__container').css('position', 'fixed');
    });
</script>

<!-- MathJax Load-->


                </main>
            </div>
        </body>
    
</html>
